package cn.ywyu.classfinal.constant;

import cn.ywyu.classfinal.enums.FrameworkEnum;

import java.util.Arrays;
import java.util.List;

/**
 * 常量
 */
public class Const {
    public static final String AUTHOR = "NYG";
    // 版本
    public static final String VERSION = "v1.3.2";
    // 加密出来的文件名
    public static final String FILE_NAME = ".classes";
    // lib下的jar解压的目录名后缀
    public static final String LIB_JAR_DIR = "__temp__";
    // 默认加密方式
    public static final int ENCRYPT_TYPE = 1;
    // 类后缀
    public static final String CLASS_SUFFIX = ".class";

    //密码文件存放路径标记
    public static final String CONFIG_PASS_PATH = "org.springframework.config.PassPath";
    // 密码标记
    public static final String CONFIG_PASS = "org.springframework.config.Pass";
    // 机器码标记
    public static final String CONFIG_CODE = "org.springframework.config.Code";
    // 加密密码的hash
    public static final String CONFIG_PASS_HASH = "org.springframework.config.PassHash";


    // 本项目需要打包的代码
    public static final List<String> CLASSFINAL_FILES = Arrays.asList(
            "Const.class", "FrameworkEnum.class",
            "JarDecryptor.class",
            "CoreAgent.class", "PasswordInputForm.class", "PasswordInputForm$PasswordKeyAdapter.class", "AgentTransformer.class",
            "EncryptUtils.class", "IoUtils.class", "JarUtils.class", "Log.class", "StrUtils.class", "SysUtils.class",
            "CmdLineParser.class", "CmdLineParser$CmdOpts.class"
    );
    // 启用的框架
    public static final List<FrameworkEnum> ENABLED_FRAMEWORKS = Arrays.asList(
            FrameworkEnum.SPRING
    );
    // 颜色
    private static final int[] COLOR_ARRAY = {31, 32, 33, 34, 35, 36, 90, 92, 93, 94, 95, 96};

    /**
     * 打印信息
     */
    public static void printInfo() {
        enhancedPrint();
    }

    /**
     * 增强打印
     */
    private static void enhancedPrint() {
        boolean needColor = false;//!System.getProperty("os.name").contains("Windows");
        String firstRowMsg = applyColor(needColor, 31, "Java ")
                .concat(applyColor(needColor, 92, "Class "))
                .concat(applyColor(needColor, 95, "Encryption "))
                .concat(applyColor(needColor, 96, "Tool "))
                .concat(applyColor(needColor, 37, VERSION));
//                .concat("   ")
//                .concat(applyColor(needColor, 0, "by "))
//                .concat(applyColor(needColor, 91, AUTHOR));
        System.out.println(generateStyledConsoleMessage(needColor, 57, firstRowMsg));
    }

    /**
     * 生成带有样式的Console消息
     *
     * @param isWin 是否是Windows
     * @param width 控制台宽度
     * @param rows  消息内容
     * @return 带有样式的Console消息
     */
    private static String generateStyledConsoleMessage(boolean isWin, int width, String... rows) {
        // 内容墙宽度
        int contentWallWidth = 1;
        // 内容行数
        int contentHeight = rows.length + 2;
        // 输出内容
        StringBuilder consoleMsg = new StringBuilder();

        // 调整控制台宽度以适应内容
        for (String row : rows) {
            int rowLen = row.replaceAll("\\u001B\\[[;\\d]*m", "").length() + 2 * contentWallWidth;
            if (rowLen > width) {
                width = rowLen;
            }
        }
        consoleMsg.append("\n");
        // 顶部
        printTopLine(isWin, width, contentWallWidth, contentHeight, consoleMsg);
        // 内容墙和内容部分
        printContentRows(isWin, width, contentWallWidth, rows, consoleMsg);
        // 底部
        printBottomLine(isWin, width, contentWallWidth, contentHeight, consoleMsg);
        return consoleMsg.toString();
    }

    private static void printTopLine(boolean isWin, int width, int contentWallWidth, int contentHeight, StringBuilder consoleMsg) {
        for (int i = 0; i < width; i++) {
            consoleMsg.append(applyColor(isWin, COLOR_ARRAY[i % COLOR_ARRAY.length], "="));
        }
        consoleMsg.append("\n");
        for (int i = 0; i < width; i++) {
            if (i < contentWallWidth) {
                consoleMsg.append(applyColor(isWin, COLOR_ARRAY[((width + contentHeight) * 2 - 1) % COLOR_ARRAY.length], "="));
            } else if (i >= width - contentWallWidth) {
                consoleMsg.append(applyColor(isWin, COLOR_ARRAY[width % COLOR_ARRAY.length], "="));
            } else {
                consoleMsg.append(" ");
            }
        }
        consoleMsg.append("\n");
    }

    private static void printContentRows(boolean isWin, int width, int contentWallWidth, String[] rows, StringBuilder consoleMsg) {
        for (int i = 0; i < rows.length; i++) {
            int rowLen = rows[i].replaceAll("\\u001B\\[[;\\d]*m", "").length();
            int leftBlankLen = (width - 2 * contentWallWidth - rowLen) / 2;
            for (int j = 0; j < width; j++) {
                if (j < contentWallWidth) {
                    consoleMsg.append(applyColor(isWin, COLOR_ARRAY[((width + 2 * rows.length) - 2 - i) % COLOR_ARRAY.length], "="));
                } else if (j >= width - contentWallWidth) {
                    consoleMsg.append(applyColor(isWin, COLOR_ARRAY[(width + 1 + i) % COLOR_ARRAY.length], "="));
                } else {
                    if (j == contentWallWidth + leftBlankLen) {
                        consoleMsg.append(rows[i]);
                        j += rowLen - 1;
                    } else {
                        consoleMsg.append(" ");
                    }
                }
            }
            consoleMsg.append("\n");
        }
    }

    private static void printBottomLine(boolean isWin, int width, int contentWallWidth, int contentHeight, StringBuilder consoleMsg) {
        for (int i = 0; i < width; i++) {
            if (i < contentWallWidth) {
                consoleMsg.append(applyColor(isWin, COLOR_ARRAY[(width * 2 + contentHeight) % COLOR_ARRAY.length], "="));
            } else if (i >= width - contentWallWidth) {
                consoleMsg.append(applyColor(isWin, COLOR_ARRAY[(width + contentHeight - 1) % COLOR_ARRAY.length], "="));
            } else {
                consoleMsg.append(" ");
            }
        }
        consoleMsg.append("\n");

        for (int i = 2 * width; i > width; i--) {
            consoleMsg.append(applyColor(isWin, COLOR_ARRAY[(i - 1 + contentHeight) % COLOR_ARRAY.length], "="));
        }
        consoleMsg.append("\n");
    }

    /**
     * 应用颜色
     *
     * @param needColor 是否是需要颜色
     * @param color     颜色
     * @param text      内容
     * @return 颜色+内容
     */
    private static String applyColor(boolean needColor, int color, String text) {
        return needColor ? applyColor(color, text) : text;
    }

    /**
     * 应用颜色
     *
     * @param color 颜色
     * @param text  内容
     * @return 颜色+内容
     */
    private static String applyColor(int color, String text) {
        return "\033[" + color + "m" + text + "\033[0m";
    }
}
